Assembly Language
©
Copyright Brian Brown, 1988-2000. All rights reserved.
| Notes | Home Page |
ASSEMBLY LANGUAGE PROGRAMMING, Part 4
DATA CONVERSION ROUTINES
Computer systems use character based
keyboards and displays for inputting and outputting data. Conversion routines
are necessary to convert data types to character strings and back again.
Consider the entry from a keyboard of an integer value 276. This represents a three character sequence of '2', '7' and '6'. This character sequence will need to be converted into an appropriate 16bit value representing an integer. Also consider displaying the value of a byte as two hex digits. Each nibble must be converted to an ASCII character before displaying on the terminal screen.
AFH becomes 41H 46H
The algorithm for this is
GET DIGIT MASK OFF HIGH NIBBLE CONVERT TO ASCII MASK OFF LOW NIBBLE CONVERT TO ASCII
The following code shows an MC6802 implementation.
CPU 6802 HOF MOT ORG 0100H Val1: DFB 3FH Result: DFS 02H ORG 120H Start: LDAA Val1 ; get val1 PSHA ; save val1 ANDA #0F0H ; mask high byte LSRA ; shift to low nibble LSRA LSRA LSRA JSR Conv ; convert high nibble STAA Result ; store it PULA ANDA #0FH ; mask low nibble JSR Conv ; convert low nibble STAA Result+1 ; store it Exit: BRA Exit Conv: CMPA #9H ; check for digit BLS ASCZ ADDA #07 ; adjust for letter ASCZ: ADDA #30H ; adjust to ASCII RTS END Start
41H 46H becomes AFH
The algorithm for implementing this routine is,
Get Digit Subtract 30H from Digit If Digit greater than Nine Subtract 07H from Digit EndIf Shift into High Nibble and Store Get Next Digit Subtract 30H from Next Digit If Next Digit greater than Nine Subtract 07H from Next Digit EndIf OR Next Digit with stored High Nibble and Store
The following code shows an MC6802 implementation.
CPU 6802 HOF MOT ORG 0100H ASC1: DFB 33H ASC2: DFB 46H HexB: DFB 00H ORG 120H Start: LDAA ASC1 ; get first digit SUBA #30H CMPA #09H BLS If1 SUBA #07h If1: ASLA ASLA ASLA ASLA STAA HexB LDAA ASC2 ; get next digit SUBA #30H CMPA #09H BLS If2 SUBA #07h If2: ORAA HexB STAA HexB END Start
Set Product equal to Zero Set Counter equal to Eight While counter not equal to zero Left Shift Product (Multiply by 2) Shift Multiplier so bit goes into Carry If Carry bit is Set Product equals Product plus Multipicand Endif Subtract one from Counter EndWhile
The following program implements this for an MC6802.
CPU 6802 HOF MOT ORG 0100H Val1: DFB 10H Val2: DFB 20H Result: DFS 02H ORG 0120H Start: CLRA ; product MSB = zero CLRB ; product LSB = zero LDX #0008H ; multiplier = 8 Shift: CPX #0000H BEQ Exit ASLB ; shift product left 1 bit ROLA ASL Val1 ; shift multiplier left to BCC Decr ; examine next bit ADDB Val2 ; Add multiplicand to ADCA #00H ; product if carry is set Decr: DEX BRA Shift ; loop till all 8bits are done Exit: STAA Result STAB Result+1 Finish: BRA Finish END Start
Set Quotient equal to Zero Set Counter equal to Eight While Counter not equal to zero Left Shift Dividend (Multiply by 2) Left Shift Quotient If 8 MSB's of Dividend >= Divisor then MSB of Dividend = MSB of Divident - Divisor Add one to Quotient EndIf Subtract one from Counter EndWhile Remainder = MSB of Dividend
The following program implements this for an MC6802.
CPU 6802 HOF MOT ORG 0100H Val1: DFB 10H ; Dividend Val2: DFB 20H ; Divisor Quot: DFB 00H Rem: DFB 00H ORG 0120H Start: LDX #0008H ; Number of bits in Divisor CLRA LDAB Val1 ; Get Dividend Div: CPX #0000H BEQ Exit ASLB ; Shiftv Dividend and Quotient ROLA CMPA Val2 ; is subtraction successful BCS ChkCnt SUBA Val2 ; Yes, subtract and set bit in quotient INCB ChkCnt: DEX BRA Div Exit: STAB Quot STAA Rem END Start
OFFSET DFB ;offset into ASCII string BUFFER DFS ;space for ASCII string BINV DFW ;integer result BASE DFW ;base 10 value
The algorithm for implementing the routine is,
Position Offset to last character in Buffer Set Base equal to 1 Set BinV equal to zero While Offset is not zero do Get Character stored at Buffer[Offset] If character not '-' sign then Mask out high nibble Multiply by Base value Add result to Binv Base equals Base * 10 Subtract one from Offset Else Set HighBit of BinV to 1 Set Offset equal to zero Endif EndWhile
OFFSET DFB ;offset into ASCII string BUFFER DFS ;space for ASCII string BINV DFW ;integer value BASE DFW ;base 10 value
The algorithm for implementing the routine is,
Offset equals last position in Buffer Get BinV Save BinV value for later use While BinV not less than 10 Divide BinV by 10 BinV equals remainder added with 30H Store result at Buffer[Offset] Offset equals Offset - 1 EndWhile Add 30H to BinV Store result at Buffer[Offset] Restore original BinV value If highbit set on BinV Subtract one from Offset Store '-' sign at Buffer[Offset] Endif
Get Packed BCD Value into Byte Move High Nibble to Low Nibble of Byte Zero High Nibble of Byte Multiply Byte by 10 Add Low Nibble of BCD Value to Byte
The following program shows how this is implemented on the MC6802.
CPU 6802 HOF MOT ORG 0100H Val1: DFB 00H Val2: DFB 0AH ; multiply by 10 decimal Result: DFS 02H ; result of Val1 * Val2 PackBCD:DFB 93H DecVal: DFB 00H ORG 0110H Start: LDAA PackBCD LSRA ; shift high nibble to low nibble LSRA LSRA LSRA STAA Val1 ; multiply high nibble by 10 JSR Multiply LDAA PackBCD ANDA #0FH ; mask high byte ADDA Result+1 ; add to high byte * 10 STAA DecVal ; store decimal value Finish: BRA Finish Multiply: CLRA ; product MSB = zero CLRB ; product LSB = zero LDX #0008H ; multiplier = 8 Shift: CPX #0000H BEQ Exit ASLB ; shift product left 1 bit ROLA ASL Val1 ; shift multiplier left to BCC Decr ; examine next bit ADDB Val2 ; Add multiplicand to ADCA #00H ; product if carry is setDecr: DEX BRA Shift ; loop till all 8bits are done Exit: STAA Result STAB Result+1 RTS END Start